#pragma once
#ifndef _VECTORES_H
#define _VECTORES_H


template <class T>

class CVector2
{
public:

			CVector2(T _i, T _j)
			{
				m_x = _i;
				m_y = _j;
			}
	
			CVector2() :m_x(0), m_y(0){}
	virtual ~CVector2()                      {}
	T       x()                      { return m_x; }
	void    x(T _i)                  { m_x = _i; }

	T       y()                      { return m_y; }
	void    y(T _j)                  { m_y = _j; }

	CVector2	operator+(CVector2 _other)           { return CVector2(m_x + _other.x(), m_y + _other.y()); }

	CVector2	operator-(CVector2 _other)           { return CVector2(m_x - _other.x(), m_y - _other.y()); }

	CVector2	operator*(T _ctte)                  { return CVector2(m_x*_ctte, m_y*_ctte); }

	CVector2	operator/(T _ctte)                  { return CVector2(m_x / _ctte, m_y / _ctte); }

	T			operator*(CVector2 _other)           { return ((m_x*_other.x()) + (m_y*_other.y())); }

	
	T			Modulo()                             { return sqrt((m_x*m_x) + (m_y*m_y)); }

	CVector2	Normalizar()                        { return *this / (this->Modulo()); }


private:

	T m_x;
	T m_y;


};

template <class T>
class CVector3
{
public:

			CVector3(T _i, T _j, T _k)
			{
				m_x = _i;
				m_y = _j;
				m_z = _k;
			}
	
			CVector3() :m_x(0), m_y(0), m_z(0) {}
	virtual ~CVector3()                      {}
	T       x()                      { return m_x; }
	void    x(T _i)                  { m_x = _i; }

	T       y()                      { return m_y; }
	void    y(T _j)                  { m_y = _j; }

	T       z()                      { return m_z; }
	void    z(T _k)                  { m_z = _k; }

	CVector3 operator+(CVector3 _other)           { return CVector3(m_x + _other.x(), m_y + _other.y(), m_z + _other.z()); }

	CVector3 operator-(CVector3 _other)           { return CVector3(m_x - _other.x(), m_y - _other.y(), m_z - _other.z()); }

	CVector3 operator*(T _ctte)                  { return CVector3(m_x*_ctte, m_y*_ctte, m_z*_ctte); }

	CVector3 operator/(T _ctte)                  { return CVector3(m_x / _ctte, m_y / _ctte, m_z / _ctte); }

	T       operator*(CVector3 _other)           { return (m_x*_other.x()) + (m_y*_other.y()) + (m_z*_other.z()); }

	CVector3 operator^(CVector3 _other)          { return CVector3(	(m_y*_other.z()) - (m_z*_other.y()),
																	(m_z*_other.x()) - (m_x*_other.z()),
																	(m_x*_other.y()) - (m_y*_other.x()));
												 }

	T		Modulo()                             { return sqrt((m_x*m_x) + (m_y*m_y) + (m_z*m_z)); }

	CVector3 Normalizar()                        { return *this / (this->Modulo()); }


private:

	T m_x;
	T m_y;
	T m_z;
};


typedef CVector3<float> V3f;
typedef CVector3<int>	V3i;
typedef CVector2<float> V2f;
typedef CVector2<int>	V2i;


#endif